package com.cdzs.twocamera.tcp;

import android.util.Log;

import com.cdzs.twocamera.constant.Constant;
import com.cdzs.twocamera.myinterface.NettyListener;
import com.cdzs.twocamera.util.DateFormatUtil;
import com.cdzs.twocamera.util.SPUtils;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import timber.log.Timber;

/**
 * Created by M_genius on 2018/7/13.\
 * 描述:
 */

public class NettyClient {
    private String ip = null;
    private int server_port = 0;

    private static NettyClient nettyClient = new NettyClient();

    private EventLoopGroup group;

    private NettyListener listener;

    private Channel channel;

    private boolean isConnect = false;

    private int reconnectNum = Integer.MAX_VALUE;

    // 重连间隔时间
    private long reconnectIntervalTime = 5000;
    private Bootstrap bootstrap;

    // 单例
    public static NettyClient getInstance() {
        return nettyClient;
    }


    public synchronized NettyClient connect() {

        if (!isConnect) {
            if (group == null) {
                group = new NioEventLoopGroup();
            }
            if (bootstrap == null) {
                bootstrap = new Bootstrap().group(group)
                        .option(ChannelOption.SO_KEEPALIVE, true)
                        .channel(NioSocketChannel.class)
                        .handler(new NettyClientInitializer(listener));
            }

            try {
                if (SPUtils.getSharedStringData("ip") != null) {
                    ip = SPUtils.getSharedStringData("ip");
                } else {
                    ip = Constant.SERVER_IP;
                }
                if (SPUtils.getSharedIntData("server_port") != 0) {
                    server_port = SPUtils.getSharedIntData("server_port");
                } else {
                    server_port = Constant.SERVER_PORT;
                }

                bootstrap.connect(ip, server_port).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture channelFuture) throws Exception {
                        if (channelFuture.isSuccess()) {
                            isConnect = true;
                            channel = channelFuture.channel();
                        } else {
                            isConnect = false;
                        }
                    }
                }).sync();

            } catch (Exception e) {
                Timber.e(e, e.getMessage());
                listener.onServiceStatusConnectChanged(NettyListener.STATUS_CONNECT_ERROR);
                reconnect();
            }
        }
        return this;
    }

    public void disconnect() {
        group.shutdownGracefully();
    }

    public void reconnect() {
        if (reconnectNum > 0 && !isConnect) {
            reconnectNum--;
            try {
                Thread.sleep(reconnectIntervalTime);
            } catch (InterruptedException e) {
            }
            Timber.e("重新连接");
            disconnect();
            connect();
        } else {
            disconnect();
        }
    }

    public boolean sendMsgToServer(byte[] data, ChannelFutureListener listener) {
        boolean flag = channel != null && isConnect;
        if (flag) {
            ByteBuf buf = Unpooled.copiedBuffer(data);
            channel.writeAndFlush(buf).addListener(listener);
            if (data.length != 28) {
                Log.d("MainActivity", "sendPicDataPackage: 发送数据--->长度为  " + data.length);
                Log.d("MainActivity", "sendPicDataPackage: 数据包发送时间  " + DateFormatUtil.format(System.currentTimeMillis(), DateFormatUtil.DateFormatEnum.ymdhmss));
            }
        }
        return flag;
    }

    public void setReconnectNum(int reconnectNum) {
        this.reconnectNum = reconnectNum;
    }

    public void setReconnectIntervalTime(long reconnectIntervalTime) {
        this.reconnectIntervalTime = reconnectIntervalTime;
    }

    public boolean getConnectStatus() {
        return isConnect;
    }

    public void setConnectStatus(boolean status) {
        this.isConnect = status;
    }

    public void setListener(NettyListener listener) {
        this.listener = listener;
    }
}
